home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / EXTEND5.ARJ / EXTEND.PAS < prev    next >
Pascal/Delphi Source File  |  1991-02-28  |  5KB  |  127 lines

  1. {$I-,O-,R-}
  2.  
  3. unit Extend;
  4.  
  5. { This unit allows a program to open more than the standard DOS maximum of 20
  6.   open files at one time.  You must also be sure to set a FILES=XX statement
  7.   in your CONFIG.SYS file.  This program installs a special interrupt handler
  8.   under DOS 2.x, some semi-documented features under DOS 3.x prior to
  9.   DOS 3.3 and the DOS extend files call under DOS 3.3 or later.  This
  10.   unit USES the DOS unit and should be used before any other units other than
  11.   the DOS unit.  This code was based upon earlier work by Randy Forgaard, Bela
  12.   Lubkin and Kim Kokkonen.  See EXTEND.DOC for more information.
  13.  
  14.   Scott Bussinger
  15.   Professional Practice Systems
  16.   110 South 131st Street
  17.   Tacoma, WA  98444
  18.   (206)531-8944
  19.   Compuserve [72247,2671] }
  20.  
  21. { ** Revision History **
  22.   1 EXTEND.PAS 9-Mar-89,`SCOTT' First version using TLIB -- Based on 3.2
  23.   2 EXTEND.PAS 15-Sep-89,`SCOTT'
  24.            Added SwapVectorsExtend procedure
  25.            Put handle table into DOS memory
  26.            Use DOS 3.3 extended handles function when available
  27.   3 EXTEND.PAS 2-Oct-89,`SCOTT'
  28.            Fixed bug in determining the DOS version
  29.   4 EXTEND.PAS 5-Oct-89,`SCOTT'
  30.            Yet another bug in the DosVersion detection
  31.   5 EXTEND.PAS 19-Nov-90,`SCOTT'
  32.            New version of EXTEND that is compatible with Turbo Pascal 6.0
  33.            Modified the documentation and version numbers to be less confusing
  34.   6 EXTEND.PAS 28-Feb-91,`SCOTT'
  35.            New version compiled with fixed SHRINK.PAS to fix problems with TP6
  36.   ** Revision History ** }
  37.  
  38. interface
  39.  
  40. procedure SwapVectorsExtend;
  41.   { Swap interrupt vectors taken over by Extend unit with system vectors }
  42.  
  43. implementation
  44.  
  45. uses Dos,Shrink;
  46.  
  47. type HandleArray = array[0..254] of byte;        { Room for 255 handles }
  48.      HandleArrayPtr = ^HandleArray;
  49.  
  50. var DosMemory: pointer;                          { Pointer to memory gained from DOS }
  51.     ExitSave: pointer;                           { Previous exit procedure }
  52.     OldInt21: pointer;                           { Save old INT 21 }
  53.     OldHandleTable: HandleArrayPtr;              { Pointer to original table }
  54.     OldNumHandles: byte;                         { Original number of handles }
  55.  
  56. {$L EXTEND }
  57. procedure ExtendInit; external;                  { Initialize interrupt handler }
  58. procedure ExtendHandler; external;               { Replacement INT 21 handler }
  59.  
  60. procedure SwapVectorsExtend;
  61.   { Swap interrupt vectors taken over by Extend unit with system vectors }
  62.   var TempVector: pointer;
  63.   begin
  64.   if lo(DosVersion) = 2 then
  65.     begin
  66.     GetIntVec($21,TempVector);                   { Swap the INT 21 vectors }
  67.     SetIntVec($21,OldInt21);
  68.     OldInt21 := TempVector
  69.     end
  70.   end;
  71.  
  72. procedure ExtendHandles;
  73.   { Install the extended handles interrupt.  No files (other than
  74.     standard handles) should be open when unit starts up. }
  75.   var Regs: Registers;
  76.   begin
  77.   if lo(DosVersion) = 2
  78.    then
  79.     begin
  80.     GetIntVec($21,OldInt21);                     { Install interrupt handler under DOS 2.x }
  81.     ExtendInit;                                  { Initialize the interrupt handler }
  82.     SetIntVec($21,@ExtendHandler)
  83.     end
  84.    else
  85.     begin
  86.     DosNewShrink(DosMemory,sizeof(HandleArray));
  87.     if DosMemory <> nil then                     { There wasn't enough memory for a handle table, so just quit }
  88.       if (lo(DosVersion)>=4) or (hi(DosVersion)>=30) { Does this DOS version support the handles call? }
  89.        then
  90.         begin
  91.         DosDispose(DosMemory);                   { Free up the DOS memory block so that the next function will succeed }
  92.         with Regs do
  93.           begin
  94.           AH := $67;                             { Tell DOS to allow us 255 handles }
  95.           BX := 255;                             { KEEP THIS NUMBER ODD TO AVOID BUG IN SOME VERSIONS OF DOS 3.3!! }
  96.           MsDos(Regs)
  97.           end
  98.         end
  99.        else
  100.         begin
  101.         fillchar(DosMemory^,sizeof(HandleArray),$FF);     { Initialize new handles as unused }
  102.         OldNumHandles := mem[prefixseg:$0032];            { Get old table length }
  103.         OldHandleTable := pointer(ptr(prefixseg,$0034)^); { Save address of old table }
  104.         mem[prefixseg:$0032] := sizeof(HandleArray);      { Set new table length }
  105.         pointer(meml[prefixseg:$0034]) := DosMemory;      { Point to new handle table }
  106.         move(OldHandleTable^,DosMemory^,OldNumHandles)    { Copy the current handle table to the new handle table }
  107.         end
  108.     end
  109.   end;
  110.  
  111. {$F+}
  112. procedure ExitHandler;
  113. {$F-}
  114.   { Uninstall the extended handles interrupt.  All files (other
  115.     than standard handles) should be closed before unit exits. }
  116.   begin
  117.   ExitProc := ExitSave;                          { Chain to next exit routine }
  118.   SwapVectorsExtend                              { Restore original interrupt vectors }
  119.   end;
  120.  
  121. begin
  122. ExitSave := ExitProc;                            { Remember the previous exit routine }
  123. ExitProc := @ExitHandler;                        { Install our exit routine }
  124. ExtendHandles                                    { Enable the extra handles }
  125. end.
  126.  
  127.